﻿using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.ConversionTools;
using System;
using System.IO;
using System.Windows.Forms;
using ESRI.ArcGIS.DataSourcesFile;

namespace School
{
    public partial class RasterToPolygonForm : Form
    {
        private AxMapControl _mapControl;
        private Geoprocessor _geoprocessor;

        public RasterToPolygonForm(AxMapControl mapControl)
        {
            InitializeComponent();
            _mapControl = mapControl;
            _geoprocessor = new Geoprocessor();
            _geoprocessor.OverwriteOutput = true;
        }

        private void RasterToPolygonForm_Load(object sender, EventArgs e)
        {
            cboLayers.Items.Clear();

            if (_mapControl.LayerCount == 0)
            {
                MessageBox.Show("地图中没有图层!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Close(); // 关闭窗体
                return;
            }

            for (int i = 0; i < _mapControl.LayerCount; i++)
            {
                ILayer layer = _mapControl.get_Layer(i);
                if (layer is IRasterLayer)
                {
                    cboLayers.Items.Add(layer.Name);
                }
            }

            if (cboLayers.Items.Count > 0)
            {
                cboLayers.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("地图中没有栅格图层!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Close(); // 无栅格图层时关闭窗体
            }
        }

        private void cboLayers_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 此处因删除标签显示，无需操作
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveDialog = new SaveFileDialog())
            {
                saveDialog.Filter = "Shapefile (*.shp)|*.shp";
                saveDialog.Title = "选择输出路径";

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    txtOutputPath.Text = saveDialog.FileName;
                }
            }
        }

        private void btnConvert_Click(object sender, EventArgs e)
        {
            try
            {
                if (cboLayers.SelectedIndex < 0)
                {
                    MessageBox.Show("请选择栅格图层!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (string.IsNullOrEmpty(txtOutputPath.Text))
                {
                    MessageBox.Show("请指定输出路径!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                string layerName = cboLayers.SelectedItem.ToString();
                IRasterLayer selectedLayer = null;

                for (int i = 0; i < _mapControl.LayerCount; i++)
                {
                    ILayer layer = _mapControl.get_Layer(i);
                    if (layer.Name == layerName && layer is IRasterLayer rasterLayer)
                    {
                        selectedLayer = rasterLayer;
                        break;
                    }
                }

                if (selectedLayer == null)
                {
                    MessageBox.Show("找不到选中的栅格图层!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                string outputPath = txtOutputPath.Text;
                string outputDir = Path.GetDirectoryName(outputPath);

                if (!Directory.Exists(outputDir))
                {
                    Directory.CreateDirectory(outputDir);
                }

                txtLog.Clear();
                Application.DoEvents();

                // 创建并配置栅格转面工具
                RasterToPolygon rasterToPolygon = new RasterToPolygon();
                rasterToPolygon.in_raster = selectedLayer;
                rasterToPolygon.out_polygon_features = outputPath;
                rasterToPolygon.simplify = chkSimplify.Checked ? "SIMPLIFY" : "NO_SIMPLIFY";

                // 执行转换
                object processResult = _geoprocessor.Execute(rasterToPolygon, null);

                if (_geoprocessor.MessageCount > 0)
                {
                    for (int i = 0; i < _geoprocessor.MessageCount; i++)
                    {
                        txtLog.AppendText(_geoprocessor.GetMessage(i) + Environment.NewLine);
                    }
                }

                if (processResult != null)
                {
                    MessageBox.Show("栅格转面成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    AddResultToMap(outputPath);
                }
                else
                {
                    MessageBox.Show("栅格转面失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"执行转换时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void AddResultToMap(string shpPath)
        {
            try
            {
                IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass();
                string workspacePath = Path.GetDirectoryName(shpPath);
                IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFactory.OpenFromFile(workspacePath, 0);
                string featureClassName = Path.GetFileNameWithoutExtension(shpPath);
                IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(featureClassName);

                // 添加字段（如果不存在）

                AddFieldIfNotExists(featureClass, "Shape_Area", esriFieldType.esriFieldTypeDouble);

                // 计算字段值
                CalculateShapeFields(featureClass);

                IFeatureLayer featureLayer = new FeatureLayerClass();
                featureLayer.FeatureClass = featureClass;
                featureLayer.Name = Path.GetFileName(shpPath);

                _mapControl.AddLayer(featureLayer);
                _mapControl.ActiveView.Refresh();

                MessageBox.Show("结果已添加到地图，并计算了面积!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加结果到地图时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 辅助方法：添加字段（如果不存在）
        private void AddFieldIfNotExists(IFeatureClass featureClass, string fieldName, esriFieldType fieldType)
        {
            if (featureClass.FindField(fieldName) == -1)
            {
                IField field = new FieldClass();
                IFieldEdit fieldEdit = (IFieldEdit)field;
                fieldEdit.Name_2 = fieldName;
                fieldEdit.Type_2 = fieldType;
                featureClass.AddField(field);
            }
        }

        // 辅助方法：计算几何字段值
        private void CalculateShapeFields(IFeatureClass featureClass)
        {
            int areaIndex = featureClass.FindField("Shape_Area");

            IFeatureCursor updateCursor = featureClass.Update(null, true);
            IFeature feature = updateCursor.NextFeature();

            try
            {
                while (feature != null)
                {
                    ESRI.ArcGIS.Geometry.IGeometry geometry = feature.ShapeCopy;
                    if (geometry != null && geometry.GeometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon)
                    {
                        // 显式转换为 IArea 接口
                        ESRI.ArcGIS.Geometry.IArea area = (ESRI.ArcGIS.Geometry.IArea)geometry;
                        double areaValue = area.Area;

                        // 设置字段值
                        feature.set_Value(areaIndex, areaValue);

                        // 输出格式化后的数值到日志
                        txtLog.AppendText($"要素 ID: {feature.OID}, 面积: {areaValue:N2} 平方米" + Environment.NewLine);

                        updateCursor.UpdateFeature(feature);
                    }
                    feature = updateCursor.NextFeature();
                }
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(updateCursor);
            }
        }
    }
}